package com.agua.enturno.servicios.impl;

import com.agua.enturno.excepciones.ExcepcionDeReglaDelNegocio;
import com.agua.enturno.modelo.agenda.JornadaLaboralOcasional;
import com.agua.enturno.persistencia.dao.JornadaLaboralOcasionalDAO;
import com.agua.enturno.servicios.JornadaLaboralOcasionalService;
import com.agua.enturno.vista.dto.HorarioDTO;
import com.agua.enturno.vista.dto.HorarioFullDTO;
import com.agua.enturno.vista.dto.JornadaLaboralOcasionalDTO;
import com.agua.enturno.vista.dto.assemblers.HorarioAssembler;
import com.agua.enturno.vista.dto.assemblers.HorarioFullAssembler;
import com.agua.enturno.vista.dto.assemblers.JornadaLaboralOcasionalAssembler;
import org.joda.time.Duration;
import org.joda.time.Interval;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

public class JornadaLaboralOcasionalServiceImpl implements JornadaLaboralOcasionalService {

	private JornadaLaboralOcasionalDAO jornadaLaboralOcasionalDAO;
	private JornadaLaboralOcasionalAssembler jornadaLaboralOcasionalAssembler;
	private HorarioAssembler horarioAssembler;
	private HorarioFullAssembler horarioFullAssembler;
	
	
	/*------------------------------------ Public methods ----------------------------------*/

	@Override
	@Transactional
	public JornadaLaboralOcasionalDTO findById(Long jornadaId) {
		return jornadaLaboralOcasionalAssembler.assemble(jornadaLaboralOcasionalDAO.findById(jornadaId));
	}
	
	@Override
	@Transactional
	public List<HorarioDTO> findHorarios(Long jornadaId) {
		return horarioAssembler.assemble(jornadaLaboralOcasionalDAO.findById(jornadaId).getHorarios());
	}
	
	@Override
	@Transactional
	public List<HorarioFullDTO> findHorariosFull(Long jornadaId) {
		return horarioFullAssembler.assemble(jornadaLaboralOcasionalDAO.findById(jornadaId).getHorarios());
	}
	
	@Override
	@Transactional
	public void modificarJornada(Long jornadaId, JornadaLaboralOcasionalDTO jornadaOcasionalModificadaDTO, String motivo) throws ExcepcionDeReglaDelNegocio {
		
		try {
			
			Interval intervalo = new Interval(jornadaOcasionalModificadaDTO.getInicio(), jornadaOcasionalModificadaDTO.getFin());
			
			JornadaLaboralOcasional jornadaOcasional = jornadaLaboralOcasionalDAO.findById(jornadaId);
			jornadaOcasional.modificarIntervalo(intervalo, motivo);
			jornadaOcasional.modificarDuracionDeLosTurnos(jornadaOcasionalModificadaDTO.getDuracionDeLosTurnos());
			jornadaOcasional.modificarVacantesPorTurno(jornadaOcasionalModificadaDTO.getVacantesPorTurno(), motivo);
			
		} catch (IllegalArgumentException e) {
			throw new ExcepcionDeReglaDelNegocio("El fin de la jornada debe ser posterior al inicio de la mísma");
		}
	}
	
	@Override
	@Transactional
	public void modificarIntervalo(Long jornadaId, Interval nuevoIntervalo, String motivo) throws ExcepcionDeReglaDelNegocio {
		JornadaLaboralOcasional jornadaOcasional = jornadaLaboralOcasionalDAO.findById(jornadaId);
		jornadaOcasional.modificarIntervalo(nuevoIntervalo, motivo);
	}
	
	@Override
	@Transactional
	public void modificarDuracionDeLosTurnos(Long jornadaId, Duration nuevaDuracion) throws ExcepcionDeReglaDelNegocio {
		JornadaLaboralOcasional jornadaOcasional = jornadaLaboralOcasionalDAO.findById(jornadaId);
		jornadaOcasional.modificarDuracionDeLosTurnos(nuevaDuracion);
	}
	
	@Override
	@Transactional
	public void agregarVacantesPorTurno(Long jornadaId, Integer vacantesAAgregar) throws ExcepcionDeReglaDelNegocio {
		JornadaLaboralOcasional jornadaOcasional = jornadaLaboralOcasionalDAO.findById(jornadaId);
		jornadaOcasional.agregarVacantesPorTurno(vacantesAAgregar);
	}

	@Override
	@Transactional
	public void quitarVacantesPorTurno(Long jornadaId, Integer vacantesAQuitar, String motivo) throws ExcepcionDeReglaDelNegocio {
		JornadaLaboralOcasional jornadaOcasional = jornadaLaboralOcasionalDAO.findById(jornadaId);
		jornadaOcasional.quitarVacantesPorTurno(vacantesAQuitar, motivo);
	}
	
	/*--------------------------------------------------------------------------------------*/
	/*---------------------------------- Geters and seters ---------------------------------*/

	public void setJornadaLaboralOcasionalDAO(JornadaLaboralOcasionalDAO jornadaLaboralOcasionalDAO) {
		this.jornadaLaboralOcasionalDAO = jornadaLaboralOcasionalDAO;
	}

	public void setJornadaLaboralOcasionalAssembler(JornadaLaboralOcasionalAssembler jornadaLaboralOcasionalAssembler) {
		this.jornadaLaboralOcasionalAssembler = jornadaLaboralOcasionalAssembler;
	}

	public void setHorarioAssembler(HorarioAssembler horarioAssembler) {
		this.horarioAssembler = horarioAssembler;
	}

	public void setHorarioFullAssembler(HorarioFullAssembler horarioFullAssembler) {
		this.horarioFullAssembler = horarioFullAssembler;
	}
	
	/*--------------------------------------------------------------------------------------*/

}
